﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters.XmlProcessor;
using OFX.Aggregator.Infrastructure;
using OFX.Aggregator.WpfApplication.Properties;

namespace OFX.Aggregator.WpfApplication
{
	/// <summary>
	/// Interaction logic for App.xaml
	/// </summary>
	public partial class App : Application
	{
		private IWindsorContainer container;

		protected override void OnStartup(StartupEventArgs e)
		{
			try
			{
				if (!Settings.Default.Loaded)
				{
					Settings.Default.Upgrade();
					Settings.Default.Loaded = true;
					Settings.Default.Save();
				}

				var containerAbstraction = new WindsorContainerAbstraction();

				SingletonContainer.Setup(containerAbstraction);

				this.container = containerAbstraction.Instance;

				this.container.Kernel.AddComponentInstance<IIoCContainerAbstraction>(typeof (IIoCContainerAbstraction),
				                                                                     containerAbstraction);
			}
			catch (ConfigurationProcessingException cpex)
			{
				MessageBox.Show((cpex.InnerException ?? cpex).Message, MainWindow.Title, MessageBoxButton.OK,
				                MessageBoxImage.Error);
				return;
			}

			base.OnStartup(e);

			if (Settings.Default != null && !string.IsNullOrEmpty(Settings.Default.ComplexSettings))
			{
				Dictionary<string, object> settingsDictionary;

				var formatter = new BinaryFormatter();
				using (var stream = new MemoryStream())
				{
					byte[] buffer = Convert.FromBase64String(Settings.Default.ComplexSettings);
					stream.Write(buffer, 0, buffer.Length);
					stream.Seek(0, SeekOrigin.Begin);

					settingsDictionary = (Dictionary<string, object>) formatter.Deserialize(stream);
				}

				var statementSourceRepository = (IStatementSourceRepository) settingsDictionary["StatementSourceRepository"];
				if (statementSourceRepository.StatementSources is BindingList<StatementSource>)
				{
					this.container.Kernel.RemoveComponent("StatementSourceRepository");
					this.container.Kernel.AddComponentInstance<IStatementSourceRepository>(typeof (IStatementSourceRepository),
					                                                                       statementSourceRepository);
				}
			}
		}

		private void Application_Exit(object sender, ExitEventArgs e)
		{
			var statementSourceRepository = this.container.Resolve<IStatementSourceRepository>();
			var settingsDictionary = new Dictionary<string, object> {{"StatementSourceRepository", statementSourceRepository}};
			var formatter = new BinaryFormatter();
			using (var stream = new MemoryStream())
			{
				formatter.Serialize(stream, settingsDictionary);

				// TODO: Add encryption
				Settings.Default.ComplexSettings = Convert.ToBase64String(stream.GetBuffer());
			}

			Settings.Default.Save();
		}
	}
}